#include <AVUITransform.h>

namespace AVUI {

/// <summary>Represents a 2-D skew. </summary>
class SkewTransform : public Transform
{
public:
    DECLARE_ELEMENT(SkewTransform, Transform);

#pragma region Public Methods

    /// <summary>Initializes a new instance of the <see cref="T:System.Windows.Media.SkewTransform" /> class.</summary>
    SkewTransform() { };

    /// <summary>Initializes a new instance of the <see cref="T:System.Windows.Media.SkewTransform" /> class that has the specified x- and y-axes angles and is centered on the origin.</summary>
    /// <param name="angleX">The x-axis skew angle, which is measured in degrees counterclockwise from the y-axis. For more information, see the <see cref="P:System.Windows.Media.SkewTransform.AngleX" /> property.</param>
    /// <param name="angleY">The y-axis skew angle, which is measured in degrees counterclockwise from the x-axis. For more information, see the <see cref="P:System.Windows.Media.SkewTransform.AngleY" /> property.</param>
    SkewTransform(float angleX, float angleY);

    /// <summary>Initializes a new instance of the <see cref="T:System.Windows.Media.SkewTransform" /> class that has the specified x- and y-axes angles and center. </summary>
    /// <param name="angleX">The x-axis skew angle, which is measured in degrees counterclockwise from the y-axis. For more information, see the <see cref="P:System.Windows.Media.SkewTransform.AngleX" /> property.</param>
    /// <param name="angleY">The y-axis skew angle, which is measured in degrees counterclockwise from the x-axis. For more information, see the <see cref="P:System.Windows.Media.SkewTransform.AngleY" /> property.</param>
    /// <param name="centerX">The x-coordinate of the transform center. For more information, see the <see cref="P:System.Windows.Media.SkewTransform.CenterX" /> property.</param>
    /// <param name="centerY">The y-coordinate of the transform center. For more information, see the <see cref="P:System.Windows.Media.SkewTransform.CenterY" /> property.</param>
    SkewTransform(float angleX, float angleY, float centerX, float centerY);

    /// <summary>Creates a modifiable copy of this <see cref="T:System.Windows.Media.SkewTransform" /> by making deep copies of its values. </summary>
    /// <returns>A modifiable deep copy of the current object. The <see cref="P:System.Windows.Freezable.IsFrozen" /> property of the cloned object returns false even if the <see cref="P:System.Windows.Freezable.IsFrozen" /> property of the source is true.</returns>
    TRefCountedPtr<SkewTransform> Clone() { return (SkewTransform*) Transform::Clone().get_Ptr(); }

    /// <summary>Creates a modifiable copy of this <see cref="T:System.Windows.Media.SkewTransform" /> object by making deep copies of its values. This method does not copy resource references, data bindings, or animations, although it does copy their current values. </summary>
    /// <returns>A modifiable deep copy of the current object. The <see cref="P:System.Windows.Freezable.IsFrozen" /> property of the cloned object is false even if the <see cref="P:System.Windows.Freezable.IsFrozen" /> property of the source is true.</returns>
    TRefCountedPtr<SkewTransform> CloneCurrentValue() { return (SkewTransform*) Transform::CloneCurrentValue().get_Ptr(); }

#pragma endregion Public Methods

#pragma region Public Properties

    /// <summary>Gets or sets the x-axis skew angle, which is measured in degrees counterclockwise from the y-axis. This is a dependency property. </summary>
    /// <returns>The skew angle, which is measured in degrees counterclockwise from the y-axis. The default is 0.</returns>
    float get_AngleX() { return AVUI::UnboxValue<float>(GetValue(get_AngleXProperty())); }
    void set_AngleX(float value) { SetValue(get_AngleXProperty(), AVUI::BoxValue(value)); } 
    DECLARE_DEPENDENCY_PROPERTY(AngleX);

    /// <summary>Gets or sets the y-axis skew angle, which is measured in degrees counterclockwise from the x-axis. This is a dependency property. </summary>
    /// <returns>The skew angle, which is measured in degrees counterclockwise from the x-axis. The default is 0.</returns>
    float get_AngleY() { return AVUI::UnboxValue<float>(GetValue(get_AngleYProperty())); }
    void set_AngleY(float value) { SetValue(get_AngleYProperty(), AVUI::BoxValue(value)); } 
    DECLARE_DEPENDENCY_PROPERTY(AngleY);

    /// <summary>Gets or sets the x-coordinate of the transform center. This is a dependency property. </summary>
    /// <returns>The x-coordinate of the transform center. The default is 0.</returns>
    float get_CenterX() { return AVUI::UnboxValue<float>(GetValue(get_CenterXProperty())); }
    void set_CenterX(float value) { SetValue(get_CenterXProperty(), AVUI::BoxValue(value)); } 
    DECLARE_DEPENDENCY_PROPERTY(CenterX);

    /// <summary>Gets or sets the y-coordinate of the transform center. This is a dependency property. </summary>
    /// <returns>The y-coordinate of the transform center. The default is 0.</returns>
    float get_CenterY() { return AVUI::UnboxValue<float>(GetValue(get_CenterYProperty())); }
    void set_CenterY(float value) { SetValue(get_CenterYProperty(), AVUI::BoxValue(value)); } 
    DECLARE_DEPENDENCY_PROPERTY(CenterY);

    /// <summary>Gets the current transformation value as a <see cref="T:System.Windows.Media.Matrix" />. </summary>
    /// <returns>The current skewing transformation value as a <see cref="T:System.Windows.Media.Matrix" />.</returns>
    virtual Matrix get_Value() AVUI_OVERRIDE;

#pragma endregion Public Properties

#pragma region Protected Methods
protected:
    virtual TRefCountedPtr<Freezable> CreateInstanceCore() AVUI_OVERRIDE { return object_allocate<SkewTransform>().get_Ptr(); }
#pragma endregion Protected Methods

#pragma region Internal Properties

    virtual bool get_IsIdentity() AVUI_OVERRIDE;

#pragma endregion Internal Properties

private:
    static void StaticConstructor();
};


typedef TRefCountedPtr<SkewTransform> SkewTransformPtr;


}; // namespace AVUI
